home *** CD-ROM | disk | FTP | other *** search
/ IRIX Base Documentation 2002 November / SGI IRIX Base Documentation 2002 November.iso / usr / share / catman / p_man / cat3dm / audiocddat / DTintro.z / DTintro
Encoding:
Text File  |  2002-10-03  |  15.0 KB  |  331 lines

  1.  
  2.  
  3.  
  4. DDDDTTTTiiiinnnnttttrrrroooo((((3333ddddmmmm))))                                                      DDDDTTTTiiiinnnnttttrrrroooo((((3333ddddmmmm))))
  5.  
  6.  
  7.  
  8. NNNNAAAAMMMMEEEE
  9.      DTintro - Introduction to the Silicon Graphics DAT Audio Library (DT)
  10.  
  11. SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
  12.      ####iiiinnnncccclllluuuuddddeeee <<<<ssssyyyyssss////ttttyyyyppppeeeessss....hhhh>>>>
  13.      ####iiiinnnncccclllluuuuddddeeee <<<<ddddmmmmeeeeddddiiiiaaaa////ddddaaaattttaaaauuuuddddiiiioooo....hhhh>>>>
  14.  
  15.      ----llllddddaaaattttaaaauuuuddddiiiioooo
  16.  
  17. DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
  18.      The Archive Python DAT (Digital Audio Tape) drive has the capability of
  19.      reading and writing audio tapes compatible with consumer and professional
  20.      DAT recorders.  This man page describes the support for handling audio
  21.      tapes in the DAT drive.  There are two components to the support: the
  22.      kernel SCSI tape driver and lllliiiibbbbddddaaaattttaaaauuuuddddiiiioooo....
  23.  
  24.    SSSSCCCCSSSSIIII TTTTaaaappppeeee DDDDrrrriiiivvvveeeerrrr
  25.      The kernel tape driver supports both regular data mode and the special
  26.      audio mode. The driver is switched between modes using the MMMMTTTTIIIIOOOOCCCCTTTTOOOOPPPP ioctl
  27.      as follows:
  28.  
  29.               struct mtop mt_com;
  30.  
  31.               mt_com.mt_op = MTAUD;
  32.               mt_com.mt_count = 1; /* 1 == audio mode, 0 == data mode */
  33.               ioctl(fd, MTIOCTOP, &mt_com);
  34.  
  35.  
  36.      The mode sticks until the tape is ejected or until a subsequent ioctl
  37.      request to switch modes.  When an audio tape is read, the driver will
  38.      automatically switch to audio mode.
  39.  
  40.      Once the driver is in audio mode the tape is read and written using the
  41.      normal _r_e_a_d(_2) and _w_r_i_t_e(_2) system calls.  Reads and writes must be done
  42.      in multiples of a DDDDTTTTFFFFRRRRAAAAMMMMEEEE,,,, [see _d_a_t_f_r_a_m_e(_4) ] the typedef describing one
  43.      frame of data on the tape otherwise your software will have no idea where
  44.      it is in the block structured audio data.
  45.  
  46.      In audio mode the tape can be repositioned using the MMMMTTTTSSSSEEEETTTTAAAAUUUUDDDDIIIIOOOO ioctl to
  47.      search for a given location in any of the three time codes or for the
  48.      start of a given program number.  For example the following code searches
  49.      for the start of program number 2.
  50.  
  51.               struct mtaudio mt_aud;
  52.  
  53.               bzero(&mt_aud, sizeof(mt_aud));
  54.               mt_aud.pno1 = 0;
  55.               mt_aud.pno2 = 0;
  56.               mt_aud.pno3 = 2;
  57.               mt_aud.seektype = MTAUDPOSN_PROG;
  58.               ioctl(fd, MTSETAUDIO, &mt_aud);
  59.  
  60.  
  61.  
  62.  
  63.                                                                         PPPPaaaaggggeeee 1111
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70. DDDDTTTTiiiinnnnttttrrrroooo((((3333ddddmmmm))))                                                      DDDDTTTTiiiinnnnttttrrrroooo((((3333ddddmmmm))))
  71.  
  72.  
  73.  
  74.      This puts the tape into a special 150X normal speed search mode.  The
  75.      tape can be rewound, also at 150X normal speed, with the MMMMTTTTIIIIOOOOCCCCTTTTOOOOPPPP ioctl
  76.      as follows:
  77.  
  78.               struct mtop mt_com;
  79.  
  80.               mt_com.mt_op = MTREW;
  81.               mt_com.mt_count = 1;
  82.               ioctl(fd, MTIOCTOP, &mt_com);
  83.  
  84.  
  85.      These commands happen in _i_m_m_e_d_i_a_t_e _m_o_d_e which means the ioctl's return
  86.      immediately.  While the tape is moving the MMMMTTTTGGGGEEEETTTTAAAAUUUUDDDDIIIIOOOO ioctl can be used
  87.      to track the progress of the tape.  To determine if the requested
  88.      operation has finished use the MMMMTTTTIIIIOOOOCCCCGGGGEEEETTTT ioctl and check the CCCCTTTT____SSSSEEEEEEEEKKKKIIIINNNNGGGG
  89.      bit in the error register.  The following code, for example, initiates a
  90.      search for program 2, then loops until the search is finished continually
  91.      requesting the current position:
  92.  
  93.               struct mtget mt_get;
  94.               struct mtaudio mt_aud;
  95.  
  96.               bzero(&mt_aud, sizeof(mt_aud));
  97.               mt_aud.pno1 = 0;
  98.               mt_aud.pno2 = 0;
  99.               mt_aud.pno3 = 2;
  100.               mt_aud.seektype = MTAUDPOSN_PROG;
  101.               ioctl(fd, MTSETAUDIO, &mt_aud);
  102.               do {
  103.                   ioctl(fd, MTGETAUDIO, &mt_aud);
  104.                   /* do something with the position information */
  105.                   ioctl(fd, MTIOCGET, &mt_get);
  106.               } while (mt_get.mt_erreg & (CT_SEEKING >> 16));
  107.  
  108.  
  109.      After the second ioctl call, mt_aud contains the program number and the
  110.      time codes (if present on the tape) of the location of the tape at the
  111.      time of the call.
  112.  
  113.    lllliiiibbbbddddaaaattttaaaauuuuddddiiiioooo
  114.      The library contains a group of utility functions for handling some
  115.      elements of the sub code data and it contains support for parsing and
  116.      understanding the complete content of the digital audio data returned by
  117.      a _r_e_a_d(_2).
  118.  
  119.      The utility functions are:  DDDDTTTTaaaattttoooottttiiiimmmmeeee,,,, DDDDTTTThhhhmmmmssssffffttttooooffffrrrraaaammmmeeee,,,, DDDDTTTTiiiinnnnccccttttiiiimmmmeeee,,,, DDDDTTTTssssbbbbttttooooaaaa,,,,
  120.      DDDDTTTTttttccccvvvvaaaalllliiiidddd,,,, DDDDTTTTttttccccttttooooffffrrrraaaammmmeeee and DDDDTTTTttttiiiimmmmeeeettttooooaaaa.... DDDDTTTTaaaattttoooottttiiiimmmmeeee converts an ASCII string
  121.      into a time code suitable for writing on the tape or using as an argument
  122.      for the MMMMTTTTSSSSEEEETTTTUUUUDDDDIIIIOOOO ioctl.  DDDDTTTTiiiinnnnccccttttiiiimmmmeeee increments such a time code.
  123.      DDDDTTTTttttccccttttooooffffrrrraaaammmmeeee converts a time code to a frame number.  DDDDTTTTttttccccvvvvaaaalllliiiidddd checks a
  124.      time code for validity.  DDDDTTTTttttiiiimmmmeeeettttooooaaaa converts a time code to ASCII.
  125.      DDDDTTTThhhhmmmmssssffffttttooooffffrrrraaaammmmeeee converts an hours, minutes, seconds, frame quadruple into a
  126.  
  127.  
  128.  
  129.                                                                         PPPPaaaaggggeeee 2222
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136. DDDDTTTTiiiinnnnttttrrrroooo((((3333ddddmmmm))))                                                      DDDDTTTTiiiinnnnttttrrrroooo((((3333ddddmmmm))))
  137.  
  138.  
  139.  
  140.      frame number.  DDDDTTTTssssbbbbttttooooaaaa converts a string encoded in the six-bit code of
  141.      the International Standard Recording Code into an ASCII string.
  142.  
  143.      lllliiiibbbbddddaaaattttaaaauuuuddddiiiioooo supports breaking down of the digital audio data into more
  144.      manageable units.  You should first read _d_a_t_f_r_a_m_e(_4) for complete details
  145.      of the format of a DDDDTTTTFFFFRRRRAAAAMMMMEEEE,,,, the block of data read from the tape.  The
  146.      DAT parser dissects the frame of data and for each data item it finds, it
  147.      can execute a function in your code to which it passes the data.  See
  148.      DDDDTTTTaaaaddddddddccccaaaallllllllbbbbaaaacccckkkk for complete details of the callback functions.  The parser
  149.      functions are DDDDTTTTccccrrrreeeeaaaatttteeeeppppaaaarrrrsssseeeerrrr,,,, DDDDTTTTddddeeeelllleeeetttteeeeppppaaaarrrrsssseeeerrrr,,,, DDDDTTTTaaaaddddddddccccaaaallllllllbbbbaaaacccckkkk,,,,
  150.      DDDDTTTTppppaaaarrrrsssseeeeffffrrrraaaammmmeeee,,,, DDDDTTTTrrrreeeesssseeeettttppppaaaarrrrsssseeeerrrr,,,, DDDDTTTTrrrreeeemmmmoooovvvveeeeccccaaaallllllllbbbbaaaacccckkkk and DDDDTTTTddddeeeelllleeeetttteeeeppppaaaarrrrsssseeeerrrr....
  151.  
  152.      The following example opens the tape drive, switches it to audio mode
  153.      then constantly reads DDDDTTTTFFFFRRRRAAAAMMMMEEEEssss from the tape and hands them to the
  154.      parser.  It has one callback set up to play the audio data The parser
  155.      will call this function with the audio data which it will have byte-
  156.      swapped and de-emphasized if the tape's pre-emphasis bit is turned on.
  157.      The example uses another callback to keep track of the sampling
  158.      frequency.
  159.  
  160.               #include <sys/types.h>
  161.               #include <sys/fcntl.h>
  162.               #include <sys/mtio.h>
  163.               #include <dmedia/audio.h>
  164.               #include <dmedia/dataudio.h>
  165.               #include <stdio.h>
  166.  
  167.               /*
  168.                * playdat.c
  169.                *
  170.                * simple DAT playing program
  171.                * adapted from the dataudio man page example code.
  172.                *
  173.                */
  174.  
  175.               #define NUMBLOCKS 4
  176.  
  177.               static     int sampsperframe = DTDA_NUMSAMPS44K;
  178.               ALport     audioport;
  179.               int isPaused;
  180.  
  181.               void
  182.               playaudio(void  *arg, DTDATATYPES type,  short *audio)
  183.               {
  184.                ALwritesamps(audioport, audio, sampsperframe);
  185.               }
  186.  
  187.               void
  188.               frequency(void  *arg, DTDATATYPES type,  int *freq)
  189.               {
  190.                switch (*freq) {
  191.                  case DT_FREQ48000:
  192.  
  193.  
  194.  
  195.                                                                         PPPPaaaaggggeeee 3333
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202. DDDDTTTTiiiinnnnttttrrrroooo((((3333ddddmmmm))))                                                      DDDDTTTTiiiinnnnttttrrrroooo((((3333ddddmmmm))))
  203.  
  204.  
  205.  
  206.                   sampsperframe =  DTDA_NUMSAMPS48K;
  207.                    break;
  208.                  case DT_FREQ44100:
  209.                    sampsperframe = DTDA_NUMSAMPS44K;
  210.                    break;
  211.                  case DT_FREQ32000:
  212.                    sampsperframe = DTDA_NUMSAMPS32K;
  213.                    break;
  214.                }
  215.               }
  216.  
  217.               main()
  218.               {
  219.                int  tape =    open("/dev/nrtape", O_RDONLY);
  220.                DTPARSER *dtp = DTcreateparser();
  221.                DTFRAME buf[NUMBLOCKS];
  222.                struct mtop    mt_com;
  223.                int  i, n;
  224.  
  225.                audioport =    ALopenport("DAT     Test", "w", 0);
  226.                if (dtp) {
  227.                   DTsetcallback(dtp, dt_audio, (DTCALLBACKFUNC)playaudio, 0);
  228.                   DTsetcallback(dtp, dt_sampfreq, (DTCALLBACKFUNC)frequency, 0);
  229.                } else
  230.                   exit(1);
  231.                if (tape >=    0) {
  232.                    mt_com.mt_op = MTAUD;
  233.                    mt_com.mt_count = 1;
  234.                    if (ioctl(tape, MTIOCTOP, &mt_com) < 0) {
  235.                     fprintf(stderr, "MTIOCTOP failed.0);
  236.                     exit(-1);
  237.                    }
  238.                    while (1) {
  239.                     while (!isPaused) {
  240.                         n =   read(tape, buf,     sizeof(buf));
  241.                         if (n < 0) {
  242.                          fprintf(stderr, "tape error! (is audio tape in drive?)0);
  243.                          exit(-1);
  244.                         }
  245.                         if (n == 0)     /* We're at the     end of the tape*/
  246.                          break;
  247.                         for   (i = 0;   i < NUMBLOCKS; i++)
  248.                          DTparseframe(dtp, &buf[i]);
  249.                     }
  250.                     while (isPaused) {
  251.                         sginap(2);
  252.                     }
  253.                    }
  254.                }
  255.                else {
  256.                    fprintf(stderr, "tape open failed0);
  257.                }
  258.  
  259.  
  260.  
  261.                                                                         PPPPaaaaggggeeee 4444
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268. DDDDTTTTiiiinnnnttttrrrroooo((((3333ddddmmmm))))                                                      DDDDTTTTiiiinnnnttttrrrroooo((((3333ddddmmmm))))
  269.  
  270.  
  271.  
  272.               exit(-1);
  273.               }
  274.  
  275.  
  276.      In deemphasis filtering floating point underflows are normal and
  277.      expected.  Thus underflows may happen when DTparseframe is called if you
  278.      have a ddddtttt____aaaauuuuddddiiiioooo callback and the incoming data is pre-emphasized.  IRIX'
  279.      default underflow handling causes a trap to the kernel on each underflow
  280.      followed by a software emulation of the calculation that produces a de-
  281.      normalized result.  The resulting value, when used in a subsequent
  282.      calculation, can cause another underflow and kernel trap.  The cycle
  283.      repeats leading to a complete loss of performance to the point where the
  284.      tape will not play in real time.
  285.  
  286.      A saner method of handling underflows in this case is to trap on the
  287.      first one and replace the result with zero.  Subsequent operations then
  288.      do not cause traps, thus performance remains at an acceptable level.  The
  289.      two lines of code in the previous example referring to sigfpe set up this
  290.      saner method of handling the exceptions.  See _s_i_g_f_p_e(_3_C) for more
  291.      details.  This code can't be put into the library because it affects
  292.      global state for the program and the programmer may not always want this
  293.      type of exception handling.  They may want the correct slow result in
  294.      some parts of their program.
  295.  
  296.      This example must be linked with ----llllffffppppeeee in addition to the libraries shown
  297.      above.
  298.  
  299. FFFFIIIILLLLEEEESSSS
  300.      /usr/include/dmedia/dataudio.h
  301.      /usr/include/mtio.h
  302.      /usr/include/sys/tpsc.h
  303.      /usr/lib/libdataudio.a /usr/share/src/dmedia/cd+dat/*     - example code
  304.  
  305. SSSSEEEEEEEE AAAALLLLSSSSOOOO
  306.      DTaddcallback(3dm), DTatohmsf(3dm), DTatotime(3dm), DTcreateparser(3dm),
  307.      DTdeleteparser(3dm), DTframetohmsf(3dm), DTframetotc(3dm),
  308.      DThmsftoframe(3dm), DTinctime(3dm), DTparseframe(3dm), DTpnotodec(3dm),
  309.      DTremovecallback(3dm), DTresetparser(3dm), DTsbtoa(3dm), DTsetdate(3dm)
  310.      DTtctoframe(3dm), DTtcvalid(3dm), DTtimetoa(3dm), datframe(4), ioctl(2),
  311.      mt(1), mtio(7), open(2), read(2), sigfpe(3C), tps(7m)
  312.  
  313. AAAAUUUUTTTTHHHHOOOORRRR
  314.      Mark Callow
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.                                                                         PPPPaaaaggggeeee 5555
  328.  
  329.  
  330.  
  331.